package com.gun3y.entity.pattern;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.htmlparser.NodeFilter;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasChildFilter;
import org.htmlparser.filters.HasParentFilter;
import org.htmlparser.filters.TagNameFilter;

import com.gun3y.entity.htmlparser.HasAttributeExFilter;
import com.gun3y.entity.htmlparser.HasSiblingExFilter;
import com.gun3y.entity.htmlparser.HasSiblingExFilter.SiblingType;
import com.gun3y.entity.htmlparser.TagNameExFilter;

public enum TagType {
    LOCAL_TAG {
	@Override
	public NodeFilter getNodeFilter(TagPattern tagPattern) {
	    return TagType.extractFilters(tagPattern);
	}
    },
    PARENT_TAG {
	@Override
	public NodeFilter getNodeFilter(TagPattern tagPattern) {
	    return new HasParentFilter(TagType.extractFilters(tagPattern), tagPattern.isRecursive());
	}
    },
    CHILD_TAG {
	@Override
	public NodeFilter getNodeFilter(TagPattern tagPattern) {
	    return new HasChildFilter(TagType.extractFilters(tagPattern), tagPattern.isRecursive());
	}
    },
    PREVIOUS_SIBLING_TAG {
	@Override
	public NodeFilter getNodeFilter(TagPattern tagPattern) {
	    return new HasSiblingExFilter(TagType.extractFilters(tagPattern), tagPattern.isRecursive(), SiblingType.PREVIOUS_SIBLING);
	}
    },
    NEXT_SIBLING_TAG {
	@Override
	public NodeFilter getNodeFilter(TagPattern tagPattern) {
	    return new HasSiblingExFilter(TagType.extractFilters(tagPattern), tagPattern.isRecursive(), SiblingType.NEXT_SIBLING);
	}
    };

    public abstract NodeFilter getNodeFilter(TagPattern tagPattern);

    private static AndFilter extractFilters(TagPattern tag) {
	List<NodeFilter> filters = new ArrayList<NodeFilter>();
	if (tag == null) {
	    return new AndFilter();
	}
	if (StringUtils.isNotBlank(tag.getTagName()) && StringUtils.isNotBlank(tag.getTagValue())) {
	    filters.add(new TagNameExFilter(tag.getTagName(), tag.getTagValue(), tag.getTagExpression()));
	}
	else if (StringUtils.isNotBlank(tag.getTagName())) {
	    filters.add(new TagNameFilter(tag.getTagName()));
	}
	else if (StringUtils.isNotBlank(tag.getTagValue())) {
	    filters.add(new TagNameExFilter(StringUtils.EMPTY, tag.getTagValue(), tag.getTagExpression()));
	}
	if (tag.getAttributes() != null) {
	    for (AttributePattern attr : tag.getAttributes()) {
		if (StringUtils.isNotBlank(attr.getAttributeName()) && StringUtils.isNotBlank(attr.getAttributeValue())) {
		    filters.add(new HasAttributeExFilter(attr.getAttributeName(), attr.getAttributeValue(), attr.getAttributeExpression()));
		}
		else if (StringUtils.isNotBlank(attr.getAttributeName()) && StringUtils.isBlank(attr.getAttributeValue())) {
		    filters.add(new HasAttributeExFilter(attr.getAttributeName()));
		}
	    }
	}
	return new AndFilter(filters.toArray(new NodeFilter[filters.size()]));
    }
}
